---
title: schema.rb (Ruby on Rails)
---

import { Tab, Tabs } from 'fumadocs-ui/components/tabs'; // For package-install code blocks

If you’re using Ruby on Rails with ActiveRecord, in most cases you can automatically generate a useful ER diagram with Liam ERD. This page provides instructions and tips for generating an ER diagram in a Rails project.

## ActiveRecord and db/schema.rb

When a Rails application manages migrations using ActiveRecord, the latest schema is typically described in `db/schema.rb`.  
Since `db/schema.rb` is recommended to be kept under version control, most projects will have it in their Git repository.

When using Liam CLI, specify `--format schemarb` and `--input db/schema.rb` as follows:

```npm
npx @liam-hq/cli erd build --format schemarb --input db/schema.rb
```

If the above command runs without issue, you should see an ER diagram generated.

## Under the Hood

- Liam CLI does not run an internal Ruby or Rails runtime. In other words, there is no Ruby process running under the hood.
- Instead, it analyzes the content of `db/schema.rb` using the [`ruby/prism` parser](https://github.com/ruby/prism).

## Trouble Shooting

### If You Don’t Have `db/schema.rb` but Use `db/structure.sql`

If your Rails app doesn’t have `db/schema.rb` and instead uses `db/structure.sql`, here’s what you need to know.

#### For Rails 7.0 or Later

Somewhere under `config` (most commonly `config/application.rb`), you may have `config.active_record.schema_format = :sql`.  
In such cases, running the dump command `rails db:schema:dump` will generate `db/structure.sql`.

If you want to obtain `db/schema.rb`, run the following in an environment with database access:

- Change `config.active_record.schema_format` to `:ruby` and run `rails db:schema:dump`.
- Alternatively, set the environment variable `SCHEMA_FORMAT=ruby` and run `rails db:schema:dump`.
  - For example: `SCHEMA_FORMAT=ruby rails db:schema:dump`

You can find sample implementations for this case on GitHub:

- GitHub Actions: [.github/workflows/rails-8-0-db-structure.yml](https://github.com/liam-hq/liam-erd-samples/blob/main/.github/workflows/rails-8-0-db-structure.yml)
- Rails App: [samples/rails-8-0-db-structure](https://github.com/liam-hq/liam-erd-samples/tree/main/samples/rails-8-0-db-structure)

#### For Rails 6.1 or Earlier

To generate `db/schema.rb` in an environment with database access, set the environment variable `SCHEMA_FORMAT=ruby` and run `rails db:schema:dump`.

#### Using `db/structure.sql` Directly

If you’re using PostgreSQL, you can hand `db/structure.sql` directly to Liam CLI, and it should be parsed correctly.

In that case, the usage is the same as [--format=postgres](/docs/parser/supported-formats/postgresql):


```npm
npx @liam-hq/cli erd build --format postgres --input db/structure.sql
```

### When Associations Don’t Appear in the ER Diagram

<Callout title="warn" type="warn">Please note that this approach can be somewhat complicated or may not work as expected.</Callout>

Liam ERD’s Rails support is specialized for analyzing a standalone `db/schema.rb` file. It does not load the entire Rails project to read associations (such as `has_many` or `belongs_to`) directly from model files.

As a result, logical relationships (associations) not backed by foreign keys may not be reflected in the ER diagram.

In some Rails projects, associations are declared in models without foreign keys in the database. In this situation, you won’t see relationships in the ER diagram.

A potential workaround—though it requires additional setup—is to manually add `add_foreign_key` statements to `db/schema.rb` in your CI/CD process, then run Liam CLI. This way, the diagram will reflect those associations.

Below is a conceptual example code snippet showing how you might gather table names from models with `belongs_to` associations and add foreign keys manually (note: this example is illustrative and may need adjustments for production use):

```ruby
# Prerequisite: The database must be accessible.
Rails.application.eager_load!

# Filter out models that have valid table_name
models_with_table = ActiveRecord::Base.descendants.select do |model|
  model.table_exists? && model.table_name.present?
end
# Map belongs_to associations to the corresponding referenced tables
assoc_map = models_with_table.map do |model|
  target_tables = model.reflect_on_all_associations(:belongs_to).map do |assoc|
    {
      table_name: assoc.class_name.safe_constantize&.table_name,
      column_name: "#{assoc.name}_id",
    }
  end.compact
  [model.table_name, target_tables]
end.to_h
# Generate add_foreign_key statements from the mapped relationships
# This is a simple example, so in practice you’d need to handle duplicates carefully
content = assoc_map.flat_map do |from_table, to_tables|
  to_tables.map { |to_table| %(add_foreign_key "#{from_table}", "#{to_table[:table_name]}", column: "#{to_table[:column_name]}") }
end.join("\n")

# Write or append this content to db/schema.rb in some way
File.open("db/schema.rb", "a") do |file|
  file.puts(content) if content.present?
end
```

By taking these steps to define foreign keys, you can produce an ER diagram closer to your expectations.

You can find sample implementations for this case on GitHub:

- GitHub Actions: [.github/workflows/rails-add-association-foreign-key.yml](https://github.com/liam-hq/liam-erd-samples/blob/main/.github/workflows/rails-add-association-foreign-key.yml)
- Rails App: [samples/rails-add-association-foreign-key](https://github.com/liam-hq/liam-erd-samples/tree/main/samples/rails-add-association-foreign-key)

## Pro Tips: Using `Schemafile` Instead of `db/schema.rb`

<Callout title="warn" type="warn">Please note that this approach can be somewhat complicated or may not work as expected.</Callout>

If your project uses a tool called [Ridgepole](https://github.com/ridgepole/ridgepole), you might have a `Schemafile` instead of a `db/schema.rb`.

A `Schemafile` uses a DSL similar to what appears in `db/schema.rb`, so handing `Schemafile` directly to Liam CLI might work in some cases.

However, because users can write arbitrary Ruby code in a `Schemafile`, there may be scenarios where it isn’t fully compatible. If the output is not what you expect, consider generating a `db/schema.rb` using the methods described above (e.g., `rails db:schema:dump`) and then parsing that file.
